const fs = require('fs')
const path = require('path')

/**
 * 复制文件夹到目标文件夹
 * @param {string} src 源目录
 * @param {string} dest 目标目录
 * @param {function} callback 回调
 */
const copyDir = (src, dest, callback) => {
  const copy = (copySrc, copyDest) => {
    fs.readdir(copySrc, (err, list) => {
      if (err) {
        callback(err)
        return
      }
      try {
        list.forEach(item => {
          const ss = path.resolve(copySrc, item)
          fs.stat(ss, (err, stat) => {
            if (err) {
              callback(err)
            } else {
              const curSrc = path.resolve(copySrc, item)
              const curDest = path.resolve(copyDest, item)

              if (stat.isFile()) {
                fs.createReadStream(curSrc).pipe(fs.createWriteStream(curDest))
              } else if (stat.isDirectory()) {
                fs.mkdirSync(curDest, { recursive: true })
                copy(curSrc, curDest)
              }
            }
          })
        })
      } catch (ex) {
        callback(err)
      }
    })
  }
  fs.access(dest, err => {
    if (err) {
      // 若目标目录不存在，则创建
      fs.mkdirSync(dest, { recursive: true })
    }
    copy(src, dest)
  })
}

function rmdir(filepath, callback) {
  fs.stat(filepath, function (err, stat) {
    if (err) return console.log(err)
    if (stat.isFile()) {
      fs.unlink(filepath, callback)
    } else {
      fs.readdir(filepath, function (err, data) {
        if (err) return console.log(err)
        let dirs = data.map(dir => path.join(filepath, dir))
        let index = 0
        !(function next() {
          if (index === dirs.length) {
            fs.rmdir(filepath, callback)
          } else {
            rmdir(dirs[index++], next)
          }
        })()
      })
    }
  })
}

/**
 * 获取某个路径下的全部文件
 * @param path 路径
 * @param whiteList 白名单
 * @param fileArr 内部递归使用
 */
function getAllFile(filePath, whiteList = [], fileArr = []) {
  return new Promise(async (resolve, reject) => {
    fs.readdir(filePath, async function (err, msg) {
      if (!err) {
        for (const item of msg) {
          if (whiteList.includes(item)) continue
          const absPath = path.join(filePath, item)
          if (fs.statSync(absPath).isDirectory()) {
            await getAllFile(absPath, whiteList, fileArr)
          } else {
            fileArr.push({
              content: fs.readFileSync(absPath),
              fileName: item,
              dirPath: filePath,
            })
          }
        }
        resolve(fileArr)
      } else {
        reject(err)
      }
    })
  })
}

/**
 * 创建目录 createDir("foo/bar"),会依次去判断上层目录是否存在，不存在则创建
 * @param dir 路径
 */
function createDir(dir) {
  if (!dir) return
  if (!fs.existsSync(dir)) {
    /** 上级路劲 */
    let tempDir = path.parse(dir).dir
    createDir(tempDir)
    fs.mkdirSync(dir, err => {
      err && console.log(err)
    })
  }
  return true
}
/**
 * 创建文件，如果目录不存在，会先创建目录
 * createFile('foo/bar/test.txt')
 * @param filePath 文件路径
 * @param content 文件内容
 * @param cb 回掉函数
 */
function createFile(filePath, content, cb) {
  /** 文件路径 */
  let fileDir = path.parse(filePath).dir
  createDir(fileDir)
  fs.writeFile(filePath, content, err => {
    cb(err)
  })
}

module.exports = { copyDir, rmdir, getAllFile, createDir, createFile }
